package com.gzhryc.shared_device.oem.h5.mng;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.xml.DOMConfigurator;

import com.gzhryc.common.StringTools;
import com.gzhryc.common.config.PropertyTools;
import com.gzhryc.common.event.DelayHandleService;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.kafka.KafkaProducerFactory;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.common.redis.RedisTools;
import com.gzhryc.jdbc.ConnectionFactory;
import com.gzhryc.jdbc.DateBranchHelper;
import com.gzhryc.jdbc.models.ConnectInfo;
import com.gzhryc.jdbc.utils.DbUtils;
import com.gzhryc.net_marketing.cloud.MarketConstants;
import com.gzhryc.net_marketing.cloud.account.HttpCallbackDelayHandler;
import com.gzhryc.net_marketing.cloud.business.event.PayOrderLogEventHandler;
import com.gzhryc.net_marketing.cloud.notice.SupplyChainNoticeService;
import com.gzhryc.servlet.VelocityService;
import com.gzhryc.shared_device.bxscn.code.services.PortableEnergyCabinetService;
import com.gzhryc.shared_device.cdb.code.services.BatteryCabinetService;
import com.gzhryc.shared_device.cdcz.code.services.ChargeSocketService;
import com.gzhryc.shared_device.common.BusyThreadPool;
import com.gzhryc.shared_device.common.CountryAreaUtils;
import com.gzhryc.shared_device.common.device.DeviceServiceFactory;
import com.gzhryc.shared_device.common.payment.dao.db.PayAccountGroup;
import com.gzhryc.shared_device.common.payment.dao.enums.ProjectWalletEnum;
import com.gzhryc.shared_device.common.payment.services.PayAccountGroupService;
import com.gzhryc.shared_device.oem.code.BaseConstants;
import com.gzhryc.shared_device.oem.code.PayServiceFactory;
import com.gzhryc.shared_device.oem.code.ResourceAPIServer;
import com.gzhryc.shared_device.oem.code.device.EDeviceFunCode;
import com.gzhryc.shared_device.oem.code.profit.service.ProjectWalletService;
import com.gzhryc.shared_device.oem.h5.mng.jetty.JettyHttpServer;
import com.gzhryc.shared_device.pcl.code.services.ChargingCableService;
import com.gzhryc.system.ManagerService;
import com.gzhryc.system.MenuService;
import com.gzhryc.system.RoleService;
import com.gzhryc.system.dto.MenuData;

public class Main {

	static Logger log = Logger.getLogger(Main.class);

	public static void main(String[] args) {
		try {
			String path = "config";
			if (args != null && args.length > 0) {
				path = args[0];
			}

			// 获取当前程序路径
			File logCfgFile = new File(path + "/log4j.xml");
			if (logCfgFile.exists()) {
				DOMConfigurator.configure(logCfgFile.getPath());
				log.info("加载" + path + "/log4j.xml日志配置信息");
			} else {
				DOMConfigurator.configure(Main.class.getClassLoader().getResource("log4j.xml"));
				log.info("加载默认log4j.xml日志配置信息");
			}

			File infoCfgFile = new File(path + "/info.properties");
			if (infoCfgFile.exists()) {
				PropertyTools.load(infoCfgFile);
				log.info("加载" + path + "/info.properties配置信息");
			} else {
				PropertyTools.load(Main.class.getClassLoader().getResourceAsStream("info.properties"));
				log.info("加载默认info.properties配置信息");
			}

			File redisCfgFile = new File(path + "/redis.properties");
			if (redisCfgFile.exists()) {
				PropertyTools tools = new PropertyTools(redisCfgFile);
				RedisTools.get().initial(tools.getProperties());
				log.info("加载" + path + "/redis.properties配置信息");
			} else {
				PropertyTools tools = new PropertyTools(Main.class.getClassLoader().getResourceAsStream("redis.properties"));
				RedisTools.get().initial(tools.getProperties());
				log.info("加载默认redis.properties配置信息");
			}

			File jdbcCfgFile = new File(path + "/jdbc.properties");
			if (jdbcCfgFile.exists()) {
				Properties properties = new Properties();
				InputStream inStream = new FileInputStream(jdbcCfgFile);
				BufferedReader bf = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
				properties.load(bf);
				ConnectInfo connectInfoCfg = new ConnectInfo(properties);
				ConnectionFactory.addDataSource(BaseConstants.JDBC_KEY, connectInfoCfg);
				ConnectionFactory.setDefaultJdbcKey(BaseConstants.JDBC_KEY);
				log.info("加载" + path + "/jdbc.properties数据库连接配置信息");
			} else {
				Properties properties = new Properties();
				properties.load(Main.class.getClassLoader().getResourceAsStream("jdbc.properties"));
				ConnectInfo connectInfoCfg = new ConnectInfo(properties);
				ConnectionFactory.addDataSource(BaseConstants.JDBC_KEY, connectInfoCfg);
				ConnectionFactory.setDefaultJdbcKey(BaseConstants.JDBC_KEY);
				log.info("加载默认jdbc.properties数据库连接配置信息");
			}
			
			if(BaseConstants.getMarket()){
				//初始化商城数据库
				File jdbcMarketCfgFile = new File(path + "/jdbc_market.properties");
				if (jdbcMarketCfgFile.exists()) {
					Properties properties = new Properties();
					InputStream inStream = new FileInputStream(jdbcMarketCfgFile);
					BufferedReader bf = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
					properties.load(bf);
					ConnectInfo connectInfoCfg = new ConnectInfo(properties);
					ConnectionFactory.addDataSource(MarketConstants.JDBC_KEY, connectInfoCfg);
					log.info("加载" + path + "/jdbc_market.properties数据库连接配置信息");
				} else {
					Properties properties = new Properties();
					properties.load(Main.class.getClassLoader().getResourceAsStream("jdbc_market.properties"));
					ConnectInfo connectInfoCfg = new ConnectInfo(properties);
					ConnectionFactory.addDataSource(MarketConstants.JDBC_KEY, connectInfoCfg);
					log.info("加载默认jdbc_market.properties数据库连接配置信息");
				}
			}

			PayServiceFactory.self().initial(PropertyTools.get().getString("httpDomain"));

			//初始化分表查询工具
			DateBranchHelper.self().setDefaultStartDate(BaseConstants.getStartDate());

			final String resDomain = PropertyTools.get().getString("resDomain");
			String resToken = PropertyTools.get().getString("resToken");
			String resId = PropertyTools.get().getString("resId");
			ResourceAPIServer.self().initial(resDomain,resToken,resId);

			//创建临时目录
			final String tempPath = PropertyTools.get().getString("tempPath");
			if(StringTools.isNotBlank(tempPath)) {
				File file = new File(tempPath);
				if (!file.exists()) {
					file.mkdirs();
				}
			}

			BusyThreadPool.self().initial();
			BusyThreadPool.self().execute(new Runnable() {
				@Override
				public void run() {
					ConnectInfo connectInfo = ConnectionFactory.getConnectInfo(BaseConstants.JDBC_KEY);

					log.info("～～～初始化数据库～～～");

					DbUtils.createDatabase(connectInfo);
					DbUtils.createTable(connectInfo, "com.gzhryc.system.dao.db");
					DbUtils.createTable(connectInfo, "com.gzhryc.log.dao.db");
					DbUtils.createTable(connectInfo, "com.gzhryc.dictionary.dao.db");

					DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.common.payment.dao.db");
					DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.common.device.dao.db");

					DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.oem.code.config.dao.db");
					DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.oem.code.member.dao.db");
					DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.oem.code.user.dao.db");
					DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.oem.code.agent.dao.db");
					DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.oem.code.place.dao.db");
					DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.oem.code.profit.dao.db");
					DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.oem.code.statistics.dao.db");
					DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.oem.code.business.dao.db");

					DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.iot.code.dao.db");
	
					//初始化地区信息
					CountryAreaUtils.initial();
					
					// 初始化菜单
					List<MenuData> menuDataList = MenuService.self().readMenuConfig(Main.class.getClassLoader().getResourceAsStream("menu_config.xml"));

					if(BaseConstants.getCDB()){
						//初始化数据库
						DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.cdb.code.dao.db");
						//初始化后台菜单
						List<MenuData> addMenuDataList = MenuService.self().readMenuConfig(Main.class.getClassLoader().getResourceAsStream("menu/menu_cdb_config.xml"));
						menuDataList = MenuService.self().merge(menuDataList,addMenuDataList);
						//初始化设备服务类
						DeviceServiceFactory.add(EDeviceFunCode.CDB.index(), BatteryCabinetService.self());
					}
					if(BaseConstants.getCDCZ()){
						//初始化数据库
						DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.cdcz.code.dao.db");
						//初始化后台菜单
						List<MenuData> addMenuDataList = MenuService.self().readMenuConfig(Main.class.getClassLoader().getResourceAsStream("menu/menu_cdcz_config.xml"));
						menuDataList = MenuService.self().merge(menuDataList,addMenuDataList);
						//初始化设备服务类
						DeviceServiceFactory.add(EDeviceFunCode.CDCZ.index(), ChargeSocketService.self());
					}
					if(BaseConstants.getBXSCN()){
						//初始化数据库
						DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.bxscn.code.dao.db");
						//初始化后台菜单
						List<MenuData> addMenuDataList = MenuService.self().readMenuConfig(Main.class.getClassLoader().getResourceAsStream("menu/menu_bxscn_config.xml"));
						menuDataList = MenuService.self().merge(menuDataList,addMenuDataList);
						//初始化设备服务类
						DeviceServiceFactory.add(EDeviceFunCode.BXSCN.index(), PortableEnergyCabinetService.self());
					}
					if(BaseConstants.getPCL()){
						//初始化数据库
						DbUtils.createTable(connectInfo, "com.gzhryc.shared_device.pcl.code.dao.db");
						//初始化后台菜单
						List<MenuData> addMenuDataList = MenuService.self().readMenuConfig(Main.class.getClassLoader().getResourceAsStream("menu/menu_pcl_config.xml"));
						menuDataList = MenuService.self().merge(menuDataList,addMenuDataList);
						//初始化设备服务类
						DeviceServiceFactory.add(EDeviceFunCode.PCL.index(), ChargingCableService.self());
					}
					//商城代码
					if(BaseConstants.getMarket()){
						ConnectInfo marketConnectInfo = ConnectionFactory.getConnectInfo(MarketConstants.JDBC_KEY);
						if(marketConnectInfo != null) {
							DbUtils.createDatabase(marketConnectInfo);
							DbUtils.createTable(marketConnectInfo, "com.gzhryc.net_marketing.cloud.account.dao.db");		//云支付账号
							DbUtils.createTable(marketConnectInfo, "com.gzhryc.net_marketing.cloud.goods.dao.db");
							DbUtils.createTable(marketConnectInfo, "com.gzhryc.net_marketing.cloud.business.dao.db");
						}
						
						//初始化后台菜单
						List<MenuData> addMenuDataList = MenuService.self().readMenuConfig(Main.class.getClassLoader().getResourceAsStream("menu/menu_market_config.xml"));
						menuDataList = MenuService.self().merge(menuDataList,addMenuDataList);
						
						//初始化微服务接口
						String marketSupplierHttpDomain = PropertyTools.get().getString("marketSupplierHttpDomain");
						SupplyChainNoticeService.self().initial(marketSupplierHttpDomain);
						
						DelayHandleService.get().run(7);
						DelayHandleService.get().addHandler(new HttpCallbackDelayHandler());		//回调延迟处理
						DelayHandleService.get().addHandler(new PayOrderLogEventHandler());
					}

					try {
						MenuService.self().refreshMenu(menuDataList,true);
						RoleService.self().readRoleConfig(Main.class.getClassLoader().getResourceAsStream("role_config.xml"));
						ManagerService.self().initialSuperAdminUser("90000");
					} catch (LogicException e) {
						log.error(e.getMessage(), e);
					}
					
					//初始化项目钱包
					List<PayAccountGroup> accountGroupList = PayAccountGroupService.self().findAll();
					if(accountGroupList != null && accountGroupList.size() > 0) {
						for(PayAccountGroup accountGroup : accountGroupList) {
							for(ProjectWalletEnum.Type type : ProjectWalletEnum.Type.values()) {
								ProjectWalletService.self().getOrAdd(type.index(), accountGroup.getId());
							}
						}
					}

					MemberTableHelper.refresh();
				}
			});

			File kafkaCfgFile = new File(path + "/kafka_producer.properties");
			if (kafkaCfgFile.exists()) {
				PropertyTools propertyTools = new PropertyTools(kafkaCfgFile);
				KafkaProducerFactory.self().initial(propertyTools.getProperties());
				log.info("消息生产者加载" + path + "/kafka_producer.properties配置信息");
			} else {
				log.info("未加载kafka_producer.properties配置信息");
			}

			// 配置模版引擎
			String webapp = PropertyTools.get().getString(WebConstants.PROGRAM_TYPE + ".webapp");
			if (StringUtils.isNotBlank(webapp)) {
				VelocityService.initial(webapp + "/views");
			} else {
				log.error("未能加载页面模版");
				return;
			}
			
			JettyHttpServer.start(path);

		} catch (IOException e) {
			log.error("程序启动失败", e);
		} catch (Exception e) {
			log.error("程序启动失败", e);
		}
	}

}
